package com.logica.mdm.webservices;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.jws.WebService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import com.logica.mdm.webservices.dao.SearchAddressDao;
import com.logica.mdm.webservices.dao.SearchPartyContractDao;
import com.logica.mdm.webservices.dao.SearchPartyDao;
import com.logica.mdm.webservices.dao.SearchPartyElectronicAddressDao;
import com.logica.mdm.webservices.dao.SearchPartyRelDao;
import com.logica.mdm.webservices.dao.SearchXrefDao;
import com.logica.mdm.webservices.dao.beans.AddressResultBean;
import com.logica.mdm.webservices.dao.beans.PartyByMdmIdResultBean;
import com.logica.mdm.webservices.dao.beans.PartyByPhoneNumberResultBean;
import com.logica.mdm.webservices.dao.beans.PartyContractResultBean;
import com.logica.mdm.webservices.dao.beans.PartyElectronicAddressResultBean;
import com.logica.mdm.webservices.dao.beans.PartyRelResultBean;
import com.logica.mdm.webservices.dao.beans.PartyResultBean;
import com.logica.mdm.webservices.dao.beans.XrefResultBean;
import com.logica.mdm.webservices.messages.SearchPartyByMdmIdRequest;
import com.logica.mdm.webservices.messages.SearchPartyByMdmIdResponse;
import com.logica.mdm.webservices.messages.SearchPartyByMdmIdUtils;
import com.logica.mdm.webservices.messages.SearchPartyByPhoneNumberRequest;
//import com.logica.mdm.webservices.messages.SearchPartyUnlimitedByPhoneNumberRequest;
import com.logica.mdm.webservices.messages.SearchPartyByPhoneNumberResponse;
import com.logica.mdm.webservices.messages.SearchPartyByPhoneNumberUtils;
import com.logica.mdm.webservices.messages.SearchPartyRequest;
import com.logica.mdm.webservices.messages.SearchPartyResponse;
import com.logica.mdm.webservices.messages.SearchPartyUtils;
import com.logica.mdm.webservices.messages.beans.AddressBean;
import com.logica.mdm.webservices.messages.beans.AddressListBean;
import com.logica.mdm.webservices.messages.beans.As400IdListBean;
import com.logica.mdm.webservices.messages.beans.ContractBean;
import com.logica.mdm.webservices.messages.beans.ContractListBean;
import com.logica.mdm.webservices.messages.beans.CrmIdListBean;
import com.logica.mdm.webservices.messages.beans.ElectronicAddressBean;
import com.logica.mdm.webservices.messages.beans.ElectronicAddressListBean;
import com.logica.mdm.webservices.messages.beans.NexibookIdListBean;
import com.logica.mdm.webservices.messages.beans.PartyWithAddressAndContractBean;
import com.logica.mdm.webservices.messages.beans.PartyWithAddressAndRelBean;
import com.logica.mdm.webservices.util.RequestWithParamsBean;

@WebService(endpointInterface = "com.logica.mdm.webservices.NexitySearchCompositeService")
public class NexitySearchCompositeServiceImpl extends
		SpringBeanAutowiringSupport implements NexitySearchCompositeService {

	private static final Logger logger = LoggerFactory
			.getLogger(NexitySearchCompositeServiceImpl.class);

	@Autowired
	private SearchPartyDao searchPartyDao;

	@Autowired
	private SearchPartyRelDao searchPartyRelDao;

	@Autowired
	private SearchAddressDao searchAddressDao;

	@Autowired
	private SearchPartyElectronicAddressDao searchPartyElectronicAddressDao;

	@Autowired
	private SearchXrefDao searchXrefDao;
	
	@Autowired
	private SearchPartyContractDao searchPartyContractDao;

	/**
	 * {@inheritDoc}
	 */
	@Override
	public SearchPartyResponse searchParty(SearchPartyRequest searchRequest) {
		SearchPartyResponse searchResponse = new SearchPartyResponse();
		//Properties properties = new Properties();
		//FileInputStream input;
		//InputStream is = this.getClass().getResourceAsStream("version.properties" );
		
		/*try {
			input = new FileInputStream("Version.properties");
			try {
				properties.load(input);
				input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} */
	      
		String validationResult = SearchPartyUtils
				.validateRequest(searchRequest);
		if (validationResult != null) {
			searchResponse.setErrorOccured(true);
			searchResponse.setMessage(validationResult);
			searchResponse.setPartyResults(null);
		} else {
			try {
				// build first request
				// Construction de la requete de recherche des C_PARTY.ROWID_OBJECT répondant aux critères de la demande webservice SOAP
				/*RequestWithParamsBean request = SearchPartyUtils
						.buildRequest(searchRequest);*/
				
				// execute first request
				// Execution de la requete de recherche des C_PARTY.ROWID_OBJECT
				/*List<PartyResultBean> response = searchPartyDao.searchParty(
						request.getSqlQuery(), request.getParams());*/
				
				// Recherche des C_PARTY.ROWID_OBJECT répondant aux critères de la demande webservice SOAP
				// Via le PLSQL PKG_SEARCHPARTY.PRC_SEARCH
				List<PartyResultBean> response = searchPartyDao.searchParty(searchRequest);
				
				// SI on a trouvé au moin un C_PARTY
				if(response != null){
					
					//set the first part of datas in the result bean
					// Alimentation de partyResults par rapports au type de recherhce (HERMES, NEXIBOOK, ALTOFFICE) à partir des 
					// infos récupérés dans la base
					List<PartyWithAddressAndContractBean> partyResults = SearchPartyUtils
							.mdmPartyListToPartyListBean(response, searchRequest.getSearchLocation());
					
					// si on a des resultats à envoyer au client du webservice
					if(partyResults != null && !partyResults.isEmpty()){						
						
						// REQUEST ----
						// Search the corresponding addresses for each C_PARTY.ROWID_OBJECT in partyResults
						RequestWithParamsBean addressRequest = SearchPartyByMdmIdUtils
								.buildListAddressRequest(partyResults);
						List<AddressResultBean> addressResponses = searchAddressDao
								.searchAddressByParty(
										addressRequest.getSqlQuery(),
										addressRequest.getParams());
						
						// Search the corresponding electronic address for each C_PARTY.ROWID_OBJECT in partyResults
						RequestWithParamsBean electronicAddressRequest = SearchPartyByMdmIdUtils
								.buildListPartyElectronicAddressRequest(partyResults);
						List<PartyElectronicAddressResultBean> electronicAddressResponse = searchPartyElectronicAddressDao
								.searchPartyElectronicAddress(
										electronicAddressRequest.getSqlQuery(),
										electronicAddressRequest.getParams());
						
						// Search the corresponding CRM IDs for each C_PARTY.ROWID_OBJECT in partyResults
						RequestWithParamsBean crmIdRequest = SearchPartyByMdmIdUtils
								.buildListPartyCrmIdRequest(partyResults);
						List<XrefResultBean> crmIdResponse = searchXrefDao
								.searchXref(crmIdRequest.getSqlQuery(),
										crmIdRequest.getParams());
						
						// Search the corresponding Logement IDs for each C_PARTY.ROWID_OBJECT in partyResults
						RequestWithParamsBean logementIdRequest = SearchPartyByMdmIdUtils
								.buildListPartyLogementIdRequest(partyResults);
						List<XrefResultBean> logementIdResponse = searchXrefDao
								.searchXref(logementIdRequest.getSqlQuery(),
										logementIdRequest.getParams());
						
						// Search the corresponding contracts for each C_PARTY.ROWID_OBJECT in partyResults
						RequestWithParamsBean contractRequest = SearchPartyByMdmIdUtils
								.buildListPartyContractRequest(partyResults);
						 List<PartyContractResultBean> contractResponse = searchPartyContractDao
								.searchPartyContract(contractRequest.getSqlQuery(),
										contractRequest.getParams());
						
						// Pour chaque individu trouvé dans la base
						// On recherche les informations complémentaires (adresse, mail,...) 
						// et on les rattache à chaque partyResults
						for(PartyWithAddressAndContractBean partyResult : partyResults){
							
							// CONVERSION ----
							// convert Address
							// Pour chaque adresse de l'individu, nettoyage, transformation de l'adresse 
							// et recopie dans addressBean
							List<AddressBean> listAddressBean = new ArrayList<AddressBean>();
							for(AddressResultBean address : addressResponses){
								if(partyResult.getMdmId().equals(address.getMdmId())){
									AddressBean addressBean = SearchPartyUtils.mdmAddressToAddressBean(address);
									listAddressBean.add(addressBean);
								}
							}
							
							// convert Electronic Address
							// Pour chaque adresse mail de l'individu, néttoyage, transformation de l'adresse 
							// et recopie dans addressBean
							List<ElectronicAddressBean> listElectronicAddressBean = new ArrayList<ElectronicAddressBean>();
							for(PartyElectronicAddressResultBean electronicAddress : electronicAddressResponse){
								if(partyResult.getMdmId().equals(electronicAddress.getMdmId())){
									ElectronicAddressBean electronicAddressBean = SearchPartyUtils.
											mdmAddressElectronicToAddressElectronicBean(electronicAddress);
									listElectronicAddressBean.add(electronicAddressBean);
								}
							}
							
							// convert CrmId
							List<String> listCrmIdBean = new ArrayList<String>();
							for(XrefResultBean crmId : crmIdResponse){
								if(partyResult.getMdmId().equals(crmId.getRowidObject())){
									String crmIdBean = crmId.getPkeySrcObject();
									listCrmIdBean.add(crmIdBean);
								}
							}
							
							// convert Logement Id
							List<String> listLogementIdBean = new ArrayList<String>();
							for(XrefResultBean logementId : logementIdResponse){
								if(partyResult.getMdmId().equals(logementId.getRowidObject())){
									String logementIdBean = logementId.getPkeySrcObject();
									listLogementIdBean.add(logementIdBean);
								}
							}
							
							// convert contract
							List<ContractBean> listContractBean = new ArrayList<ContractBean>();
							for(PartyContractResultBean contract : contractResponse){
								if(partyResult.getMdmId().equals(contract.getMdmId())){
									listContractBean.add(SearchPartyUtils.convertContractRecord(contract));
								}
							}
							
							// SET RESULT ----
							// Set the list of address
							AddressListBean addressListBean = null;
							if(!listAddressBean.isEmpty()){
								addressListBean = new AddressListBean();
								addressListBean.setAddress(listAddressBean);
							}
							partyResult.setAddressList(addressListBean);
							
							// Set the list of electronic address
							ElectronicAddressListBean electronicAddressListBean = null;
							if(!listElectronicAddressBean.isEmpty()){
								electronicAddressListBean = new ElectronicAddressListBean();
								electronicAddressListBean.setElectronicAddress(listElectronicAddressBean);
							}
							partyResult.setElectronicAddressList(electronicAddressListBean);
							
							// Set the list of crmId
							CrmIdListBean crmIdListBean = null;
							if(!listCrmIdBean.isEmpty()){
								crmIdListBean = new CrmIdListBean();
								crmIdListBean.setCrmId(listCrmIdBean);
							}
							partyResult.setCrmIdList(crmIdListBean);
							
							// Set the list of LogementId
							NexibookIdListBean nexibookIdListBean = null;
							As400IdListBean as400IdListBean = null;
							if(!listLogementIdBean.isEmpty()){
								nexibookIdListBean = new NexibookIdListBean();
								as400IdListBean = new As400IdListBean();
								nexibookIdListBean.setNexibookId(listLogementIdBean);
								as400IdListBean.setAs400Id(listLogementIdBean);
							}
							partyResult.setNexibookIdList(nexibookIdListBean);
							partyResult.setAs400IdList(as400IdListBean);
							
							// Set the list of Contract
							ContractListBean contractListBean = null;
							if(!listContractBean.isEmpty()){
								contractListBean = new ContractListBean();
								contractListBean.setContract(listContractBean);
							}
							partyResult.setContractList(contractListBean);
						}
					}
					
					//Parcourt de la liste des résultats pour vérifier si il y a des C_PARTY en doublon
					//on conserve la liste unique dans partyResults2
					
					List<PartyWithAddressAndContractBean> partyResults2 = null;
					/*if (partyResults != null){
						partyResults2 = new ArrayList<PartyWithAddressAndContractBean>();
					
						for(PartyWithAddressAndContractBean partyResult : partyResults){
							boolean bTrouve = false;
							for (PartyWithAddressAndContractBean item :partyResults2){
								if (item.getMdmId().equals(partyResult.getMdmId())){
									bTrouve = true;
									break;
								}
							}
							if (bTrouve == false){
								partyResults2.add(partyResult);
							}
						}
					}*/
					partyResults2 = partyResults;
					
					// set the result to the response
					searchResponse.setPartyResults(partyResults2);
				}
				
				// success message
					searchResponse.setMessage("The search was successful and returned "
												+ searchResponse.getPartyResults().size()
												+ " result(s)");
					
			} catch (Exception e) {
				// Log the error
				logger.error("Service searchParty failed.", e);

				// Return a null party list and indicate that an error occured
				searchResponse.setErrorOccured(true);
				searchResponse.setMessage("An error occurred: "
						+ e.getMessage());
				searchResponse.setPartyResults(null);
			}
		}

		return searchResponse;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public SearchPartyByPhoneNumberResponse searchPartyByPhoneNumber(
			SearchPartyByPhoneNumberRequest searchRequest) {
		SearchPartyByPhoneNumberResponse searchResponse = new SearchPartyByPhoneNumberResponse();

		String validationResult = SearchPartyByPhoneNumberUtils
				.validateRequest(searchRequest);
		if (validationResult != null) {
			searchResponse.setErrorOccured(true);
			searchResponse.setMessage(validationResult);
			searchResponse.setPartyResults(null);
		} else {
			try {
				RequestWithParamsBean phoneRequest = SearchPartyByPhoneNumberUtils
						.buildMdmIdRequest(searchRequest);
				List<PartyByPhoneNumberResultBean> phoneResponse = searchPartyDao
						.searchPartyByPhoneNumber(phoneRequest.getSqlQuery(),
								phoneRequest.getParams());

				List<PartyResultBean> partyResponse = null;
				if (phoneResponse != null && phoneResponse.size() > 0) {
					RequestWithParamsBean partyRequest = SearchPartyByPhoneNumberUtils
							.buildPartyRequest(phoneResponse,
									searchRequest.getRecordsToReturn());
					partyResponse = searchPartyDao.searchParty(
							partyRequest.getSqlQuery(),
							partyRequest.getParams());
				}
				
				if(partyResponse != null){
					
					//set the first part of datas in the result bean
					List<PartyWithAddressAndContractBean> partyResults = SearchPartyUtils
							.mdmPartyListToPartyListBean(partyResponse, searchRequest.getSearchLocation());
					
					if(partyResults != null && !partyResults.isEmpty()){						
						
						// REQUEST ----
						// Search the corresponding addresses
						RequestWithParamsBean addressRequest = SearchPartyByMdmIdUtils
								.buildListAddressRequest(partyResults);
						List<AddressResultBean> addressResponses = searchAddressDao
								.searchAddressByParty(
										addressRequest.getSqlQuery(),
										addressRequest.getParams());
						
						// Search the corresponding electronic address
						RequestWithParamsBean electronicAddressRequest = SearchPartyByMdmIdUtils
								.buildListPartyElectronicAddressRequest(partyResults);
						List<PartyElectronicAddressResultBean> electronicAddressResponse = searchPartyElectronicAddressDao
								.searchPartyElectronicAddress(
										electronicAddressRequest.getSqlQuery(),
										electronicAddressRequest.getParams());
						
						// Search the corresponding CRM IDs
						RequestWithParamsBean crmIdRequest = SearchPartyByMdmIdUtils
								.buildListPartyCrmIdRequest(partyResults);
						List<XrefResultBean> crmIdResponse = searchXrefDao
								.searchXref(crmIdRequest.getSqlQuery(),
										crmIdRequest.getParams());
						
						// Search the corresponding Logement IDs
						RequestWithParamsBean logementIdRequest = SearchPartyByMdmIdUtils
								.buildListPartyLogementIdRequest(partyResults);
						List<XrefResultBean> logementIdResponse = searchXrefDao
								.searchXref(logementIdRequest.getSqlQuery(),
										logementIdRequest.getParams());
						
						// Search the corresponding contracts
						RequestWithParamsBean contractRequest = SearchPartyByMdmIdUtils
								.buildListPartyContractRequest(partyResults);
						 List<PartyContractResultBean> contractResponse = searchPartyContractDao
								.searchPartyContract(contractRequest.getSqlQuery(),
										contractRequest.getParams());
						
						for(PartyWithAddressAndContractBean partyResult : partyResults){
							
							// CONVERSION ----
							// convert Address
							List<AddressBean> listAddressBean = new ArrayList<AddressBean>();
							for(AddressResultBean address : addressResponses){
								if(partyResult.getMdmId().equals(address.getMdmId())){
									AddressBean addressBean = SearchPartyUtils.mdmAddressToAddressBean(address);
									listAddressBean.add(addressBean);
								}
							}
							
							// convert Electronic Address
							List<ElectronicAddressBean> listElectronicAddressBean = new ArrayList<ElectronicAddressBean>();
							for(PartyElectronicAddressResultBean electronicAddress : electronicAddressResponse){
								if(partyResult.getMdmId().equals(electronicAddress.getMdmId())){
									ElectronicAddressBean electronicAddressBean = SearchPartyUtils.
											mdmAddressElectronicToAddressElectronicBean(electronicAddress);
									listElectronicAddressBean.add(electronicAddressBean);
								}
							}
							
							// convert CrmId
							List<String> listCrmIdBean = new ArrayList<String>();
							for(XrefResultBean crmId : crmIdResponse){
								if(partyResult.getMdmId().equals(crmId.getRowidObject())){
									String crmIdBean = crmId.getPkeySrcObject();
									listCrmIdBean.add(crmIdBean);
								}
							}
							
							// convert Logement Id
							List<String> listLogementIdBean = new ArrayList<String>();
							for(XrefResultBean logementId : logementIdResponse){
								if(partyResult.getMdmId().equals(logementId.getRowidObject())){
									String logementIdBean = logementId.getPkeySrcObject();
									listLogementIdBean.add(logementIdBean);
								}
							}
							
							// convert contract
							List<ContractBean> listContractBean = new ArrayList<ContractBean>();
							for(PartyContractResultBean contract : contractResponse){
								if(partyResult.getMdmId().equals(contract.getMdmId())){
									listContractBean.add(SearchPartyUtils.convertContractRecord(contract));
								}
							}
							
							// SET RESULT ----
							// Set the list of address
							AddressListBean addressListBean = null;
							if(!listAddressBean.isEmpty()){
								addressListBean = new AddressListBean();
								addressListBean.setAddress(listAddressBean);
							}
							partyResult.setAddressList(addressListBean);
							
							// Set the list of electronic address
							ElectronicAddressListBean electronicAddressListBean = null;
							if(!listElectronicAddressBean.isEmpty()){
								electronicAddressListBean = new ElectronicAddressListBean();
								electronicAddressListBean.setElectronicAddress(listElectronicAddressBean);
							}
							partyResult.setElectronicAddressList(electronicAddressListBean);
							
							// Set the list of crmId
							CrmIdListBean crmIdListBean = null;
							if(!listCrmIdBean.isEmpty()){
								crmIdListBean = new CrmIdListBean();
								crmIdListBean.setCrmId(listCrmIdBean);
							}
							partyResult.setCrmIdList(crmIdListBean);
							
							// Set the list of LogementId
							NexibookIdListBean nexibookIdListBean = null;
							As400IdListBean as400IdListBean = null;
							if(!listLogementIdBean.isEmpty()){
								nexibookIdListBean = new NexibookIdListBean();
								as400IdListBean = new As400IdListBean();
								nexibookIdListBean.setNexibookId(listLogementIdBean);
								as400IdListBean.setAs400Id(listLogementIdBean);
							}
							partyResult.setNexibookIdList(nexibookIdListBean);
							partyResult.setAs400IdList(as400IdListBean);
							
							// Set the list of Contract
							ContractListBean contractListBean = null;
							if(!listContractBean.isEmpty()){
								contractListBean = new ContractListBean();
								contractListBean.setContract(listContractBean);
							}
							partyResult.setContractList(contractListBean);
						}
					}
					
					List<PartyWithAddressAndContractBean> partyResults2 = null;
					if (partyResults != null){
						partyResults2 = new ArrayList<PartyWithAddressAndContractBean>();
					
						for(PartyWithAddressAndContractBean partyResult : partyResults){
							boolean bTrouve = false;
							for (PartyWithAddressAndContractBean item :partyResults2){
								if (item.getMdmId().equals(partyResult.getMdmId())){
									bTrouve = true;
									break;
								}
							}
							if (bTrouve == false){
								partyResults2.add(partyResult);
							}
						}
					}
					
					// set the result to the response
					searchResponse.setPartyResults(partyResults2);
				}
				
				searchResponse
						.setMessage("DEPRECATED!!! searchPartyByPhoneNumber is DEPRECATED!!! YOU CAN NOW USE searchParty."
								+ "The search was successful and returned "
								+ searchResponse.getPartyResults().size()
								+ " result(s)");
			} catch (Exception e) {
				// Log the error
				logger.error("Service searchPartyByPhoneNumber failed.", e);

				// Return a null party list and indicate that an error occured
				searchResponse.setErrorOccured(true);
				searchResponse.setMessage("An error occurred: "
						+ e.getMessage());
				searchResponse.setPartyResults(null);
			}
		}

		return searchResponse;
	}

	
	/**
	 * {@inheritDoc}
	 */
	/*@Override
	public SearchPartyByPhoneNumberResponse searchPartyUnlimitedByPhoneNumber(
			SearchPartyUnlimitedByPhoneNumberRequest searchRequest) {
		SearchPartyByPhoneNumberResponse searchResponse = new SearchPartyByPhoneNumberResponse();

		String validationResult = SearchPartyByPhoneNumberUtils
				.validateRequest(searchRequest);
		if (validationResult != null) {
			searchResponse.setErrorOccured(true);
			searchResponse.setMessage(validationResult);
			searchResponse.setPartyResults(null);
		} else {
			try {
				RequestWithParamsBean phoneRequest = SearchPartyByPhoneNumberUtils
						.buildMdmIdRequest(searchRequest);
				List<PartyByPhoneNumberResultBean> phoneResponse = searchPartyDao
						.searchPartyByPhoneNumber(phoneRequest.getSqlQuery(),
								phoneRequest.getParams());

				List<PartyResultBean> partyResponse = null;
				if (phoneResponse != null && phoneResponse.size() > 0) {
					RequestWithParamsBean partyRequest = SearchPartyByPhoneNumberUtils
							.buildPartyRequest(phoneResponse, null);
					partyResponse = searchPartyDao.searchParty(
							partyRequest.getSqlQuery(),
							partyRequest.getParams());
				}
				searchResponse.setPartyResults(SearchPartyUtils.convertRecord(
						partyResponse, searchRequest.getSearchLocation()));
				searchResponse = SearchPartyByPhoneNumberUtils
						.regularizeOutput(searchResponse);
				searchResponse
						.setMessage("The search was successful and returned "
								+ searchResponse.getPartyResults().size()
								+ " result(s)");
			} catch (Exception e) {
				// Log the error
				logger.error(
						"Service searchPartyUnlimitedByPhoneNumber failed.", e);

				// Return a null party list and indicate that an error occured
				searchResponse.setErrorOccured(true);
				searchResponse.setMessage("An error occurred: "
						+ e.getMessage());
				searchResponse.setPartyResults(null);
			}
		}

		return searchResponse;
	}*/

	/**
	 * {@inheritDoc}
	 */
	@Override
	public SearchPartyByMdmIdResponse searchPartyByMdmId(
			SearchPartyByMdmIdRequest searchRequest) {
		SearchPartyByMdmIdResponse searchResponse = new SearchPartyByMdmIdResponse();

		String validationResult = SearchPartyByMdmIdUtils
				.validateRequest(searchRequest);
		if (validationResult != null) {
			searchResponse.setErrorOccured(true);
			searchResponse.setMessage(validationResult);
			searchResponse.setPartyResult(null);
		} else {
			try {
				RequestWithParamsBean partyRequest = SearchPartyByMdmIdUtils
						.buildPartyRequest(searchRequest);
				PartyByMdmIdResultBean partyResponse = null;
				try {
					partyResponse = searchPartyDao.searchPartyByMdmId(
							partyRequest.getSqlQuery(),
							partyRequest.getParams());
				} catch (IncorrectResultSizeDataAccessException exc) {
					searchResponse.setErrorOccured(true);
					searchResponse
							.setMessage("An error occurred : the search returned zero or more than one party");
				}
				if (partyResponse != null) {

					PartyWithAddressAndRelBean partyResult = SearchPartyByMdmIdUtils
							.mdmPartyToPartyBean(partyResponse);

					if (partyResult != null) {
						// Search the corresponding addresses
						RequestWithParamsBean addressRequest = SearchPartyByMdmIdUtils
								.buildAddressRequest(partyResult.getMdmId());
						List<AddressResultBean> addressResponses = searchAddressDao
								.searchAddressByParty(
										addressRequest.getSqlQuery(),
										addressRequest.getParams());
						partyResult.setAddressList(SearchPartyByMdmIdUtils
								.convertAddressRecord(addressResponses));

						// Search the corresponding partyRel
						RequestWithParamsBean partyRelRequest = SearchPartyByMdmIdUtils
								.buildPartyRelRequest(partyResult.getMdmId());
						List<PartyRelResultBean> partyRelResponses = searchPartyRelDao
								.searchPartyRelByParty(
										partyRelRequest.getSqlQuery(),
										partyRelRequest.getParams());
						partyResult.setPartyRelList(SearchPartyByMdmIdUtils
								.convertPartyRelRecord(partyRelResponses,
										partyResult.getMdmId().trim()));

						// Search the corresponding electronic address
						RequestWithParamsBean electronicAddressRequest = SearchPartyByMdmIdUtils
								.buildPartyElectronicAddressProRequest(partyResult
										.getMdmId());
						List<PartyElectronicAddressResultBean> electronicAddressResponse = searchPartyElectronicAddressDao
								.searchPartyElectronicAddress(
										electronicAddressRequest.getSqlQuery(),
										electronicAddressRequest.getParams());
						partyResult
								.setElectronicAddress(SearchPartyByMdmIdUtils
										.convertPartyElectronicAddressRecord(electronicAddressResponse));

						// Search the corresponding CRM IDs
						RequestWithParamsBean crmIdRequest = SearchPartyByMdmIdUtils
								.buildPartyCrmIdRequest(partyResult.getMdmId());
						List<XrefResultBean> crmIdResponse = searchXrefDao
								.searchXref(crmIdRequest.getSqlQuery(),
										crmIdRequest.getParams());
						partyResult.setCrmId(SearchPartyByMdmIdUtils
								.convertXrefRecord(crmIdResponse));

						// Search the corresponding Logement IDs
						RequestWithParamsBean logementIdRequest = SearchPartyByMdmIdUtils
								.buildPartyLogementIdRequest(partyResult
										.getMdmId());
						List<XrefResultBean> logementIdResponse = searchXrefDao
								.searchXref(logementIdRequest.getSqlQuery(),
										logementIdRequest.getParams());
						partyResult.setNexibookId(SearchPartyByMdmIdUtils
								.convertXrefRecord(logementIdResponse));
						partyResult.setAs400Id(partyResult.getNexibookId());

						// Search the corresponding Service IDs
						// RequestWithParamsBean serviceIdRequest =
						// SearchPartyByMdmIdUtils.buildPartyServiceIdRequest(partyResult.getMdmId());
						// List<XrefResultBean> serviceIdResponse =
						// searchXrefDao.searchXref(serviceIdRequest.getSqlQuery(),
						// serviceIdRequest.getParams());
						// partyResult.setSigeoId(SearchPartyByMdmIdUtils.convertXrefRecord(serviceIdResponse));
					}

					searchResponse.setPartyResult(partyResult);

					searchResponse
							.setMessage("The search was successful and returned 1 result");
				}
			} catch (Exception e) {
				// Log the error
				logger.error("Service searchPartyByMdmId failed.", e);

				// Return a null party list and indicate that an error occured
				searchResponse.setErrorOccured(true);
				searchResponse.setMessage("An error occurred: "
						+ e.getMessage());
				searchResponse.setPartyResult(null);
			}
		}

		return searchResponse;
	}

}
